// 接口
interface Iperson {
    name: string
    age: number
    sayhi(): void
}
let person: Iperson = {
    name: '李四',
    age: 12,
    sayhi() {

    },
}
//  类型别名声明
type iperson = {
    name: string
    age: number
    sayhi(): void
}
let person1: iperson = {
    name: '张珊',
    age: 25,
    sayhi() { }
}

// 接口继承实现复用
interface Point1 { x: number, y: string }
interface Point2 { x: number, y: string, c: boolean }

// 使用继承的方式来进行代码复用
interface Point3 extends Point1 { z: number }

let person2: Point3 = {
    x: 1,
    y: 'd',
    z: 3
}

// 定义元祖类型
// 确切知道这个数组中有多少个数值，不能再添加其他的数值
let position: [number, number] = [2.555, 87.555]

// 类型推断
let age = 18
console.log(age);//如果参数直接赋值，将会推断数据的类型

function add(num1: number, num2: number) {
    return num1 + num2      //将会自动的推断返回值的类型 
}
add(1, 2)

// 类型断言
// const link = document.getElementById('link') as HTMLAnchorElement //这样提示出的类型是HTMLElement ,范围太广，不能操作他的特有属性
// 通过as指定具体的类型 ,这个可以在控制台查看具体的类型，选中标签的元素，在控制台通过console.dir()获取到他的类型 

// 字面量类型
let str1 = 'Hello Ts'
const str2 = 'Hello Ts'
// 解释：用let声明是一个变量，他的值可以是任意字符串，所以类型为：string
//       用const声明是一个常量，他的值只能是Hell Ts 所以他的类型为：Hello Ts
// 注意：此处的'Hello Ts' 就是一个字面量类型，也就是说某个特定的字符串也可以作为Ts中的类型，除字符串处，任意的js字面量（对象、数字等）都可以作为类型使用
// 当给let定义字面量类型时，这个变量就只能是这个字面量的类型
let a: 18 = 18  //字面量类型是18 其值只能是18
// 使用模式：字面量类型配合联合类型一起使用   使用场景：用来表示一组明确的可选值列表
// 贪吃蛇中，游戏的方向只能是上、下、左、右任意一个
function changDirection(direction: 'up' | 'down' | 'left' | 'right') {
    console.log(direction);
}
// 解释：参数只能是这其中的一个
// 优势：相比string类型，使用字面量类型更加精确和严谨

// 枚举
// enum direction {
//     Up,
//     Down,
//     Left,
//     Right
// }

// function ChangeDirection(Direction:direction){
//  console.log(Direction);
 
// }
// 想要调用函数，并向里面传值需要用 枚举名.定义的值  direction.Up
// ChangeDirection(direction.Down)
// 为枚举的值赋初值
enum direction {
    Up=20,
    Down=6,
    Left,
    Right
}

function ChangeDirection(Direction:direction){
 console.log(Direction);
 
}
ChangeDirection(direction.Down)

// 字符串枚举：枚举成员的值是字符串
// 注意：字符串枚举没有自增长行为，因此，字符串的每一个成员必须有初始值
enum Direction{
    Up='UP',
    Down='DOWN',
    Left='LEFT',
    Right='RIGHT'
}
function CD(DT:Direction){
    console.log(DT);
    
}
CD(Direction.Down)

// any类型
// 1、对其值进行任意的赋值
 let obj:any={}
 obj.a=1//在ts中是不能使用这种方法进行添加成员，需要在类型中定义
 console.log(obj);
//  使用场景：临时使用，避免书写很长、很复杂的类型
// 隐式具有any类型的情况：1、声明变量不提供类型，也不提供具体的值 2、函数参数不加类型

// Ts中的typeof
let p={x:1,y:2}
function formatPoint(point:typeof p){}//直接用的是定义的这个对象的类型
formatPoint({x:100,y:200})

// typeof 只能用来查询变量或属性的类型，无法查询其他形式的类型（比如函数调用的类型）
let c:typeof p.x //沿用了p中x的属性类型值
// 不能查询对象返回值的类型  let ref：typeof add(1,2)
